;;; Copyright © 2016 Eric Bavier <bavier@member.fsf.org>
;;;
;;; This program is free software.  You may run, copy, modify, and
;;; redistribute it under the terms of the GNU General Purpose License
;;; (GPL) version 3, or any later version.

(define-module (test-context-free)
  #:use-module (derivative language context-free)
  #:use-module (srfi srfi-64))

(test-begin "context-free")
(test-assert "trivial nullable"
  (and (δ 'eps)
       (δ (rep #\x))
       (not (δ 'empty))))
(test-assert "nullable"
  (δ (alt #\x 'eps)))
(test-assert "not nullable"
  (not (or (δ (alt #\x #\y))
	   (δ (cat #\x 'eps)))))
(test-assert "derivative nullable"
  (δ (D #\x (alt #\x (cat #\x #\y)))))

(test-assert "language: parens"
  (and (recognize? "()" parens-lang)
       (recognize? "((()))" parens-lang)
       (recognize? "((()())()())" parens-lang)
       (not (recognize? "((((" parens-lang))
       (not (recognize? "())" parens-lang))
       (not (recognize? "(()" parens-lang))))
(test-assert "language: ab"
  (and (not (recognize? "" ab-lang))
       (recognize? "ab" ab-lang)
       (recognize? "aaabbb" ab-lang)
       (not (recognize? "aabbb" ab-lang))))
(test-assert "language: palindrome"
  (and (recognize? "" palindrome-lang)
       (recognize? "aa" palindrome-lang)
       (recognize? "bb" palindrome-lang)
       (recognize? "abba" palindrome-lang)
       (recognize? "abaaba" palindrome-lang)
       (recognize? "babaabab" palindrome-lang)
       (not (recognize? "ab" palindrome-lang))
       (not (recognize? "babbabba" palindrome-lang))))
(test-assert "language: double"
  (and (recognize? "" double-lang)
       (recognize? "abaabb" double-lang)
       (recognize? "aababb" double-lang)
       (recognize? "ababab" double-lang)))
(test-assert "language: N+N"
  (and (not (recognize? "" N-lang))
       (recognize? "N+N" N-lang)
       (recognize? "N+N+N" N-lang)
       (recognize? "N+N+N+N" N-lang)
       (not (recognize? "N++N" N-lang))
       (not (recognize? "N+N+NN" N-lang))))
(test-assert "language: aab"
  (and (not (recognize? "" aab-lang))
       (not (recognize? "ab" aab-lang))
       (recognize? "aab" aab-lang)
       (recognize? "aaaaab" aab-lang)
       (recognize? "aaaaabb" aab-lang)
       (recognize? "aaaabbb" aab-lang)))

(test-end "context-free")
